<script setup lang="ts">
interface Props {
  waveCount?: number
  waveHeight?: number
  waveColor?: string
  waveSpeed?: number
  bgColor?: string
  offsetY?: number
  height?: string
}

const props = withDefaults(defineProps<Props>(), {
  waveCount: 2,
  waveHeight: 70,
  waveColor: 'green',
  waveSpeed: 5000,
  bgColor: '#fff',
  offsetY: 70,
  height: '140px',
})

const canvasRef = ref<HTMLCanvasElement>()

const wavePlay = (
  canvasEl: HTMLCanvasElement,
  wCount: number,
  wHeight: number,
  wColor: string,
  offY: number,
  waveSpeed: number) => {
  const { clientWidth, clientHeight } = canvasEl
  canvasEl.width = clientWidth
  canvasEl.height = clientHeight
  const ctx = canvasEl.getContext('2d')

  const waveCount = wCount // 水波个数
  const waveWidth = clientWidth / waveCount // 水波宽度
  const waveHeight = wHeight // 水波高度

  const startX = -waveWidth * waveCount
  const offsetY = offY

  let offset = 0
  const move = () => {
    if (!ctx)
      return

    offset += 5
    if (offset >= waveWidth * waveCount)
      offset = 0

    // 清除画布
    ctx.clearRect(0, 0, clientWidth, clientHeight)
    ctx.beginPath()
    ctx.fillStyle = wColor
    // 起点
    ctx.moveTo(startX + offset, offsetY)

    let cpx = startX + offset + waveWidth / 2
    let x = startX + offset + waveWidth
    let up = true

    for (let i = 0; i < waveCount * 2; i++) {
      const cpy = up ? (offsetY - waveHeight) : (offsetY + waveHeight)
      ctx.quadraticCurveTo(cpx, cpy, x, offsetY)
      cpx += waveWidth
      x += waveWidth
      up = !up
    }

    // * 2 因为画了2倍 quadraticCurveTo
    ctx.lineTo(startX + offset + waveWidth * waveCount * 2, clientHeight)
    ctx.lineTo(startX + offset, clientHeight)
    ctx.fill()

    const speed = waveSpeed > 0 ? (waveSpeed / 60) : 80
    setTimeout(move, speed)
  }

  move()
}

const toWavePlay = () => {
  if (canvasRef.value) {
    wavePlay(
      canvasRef.value,
      props.waveCount,
      props.waveHeight,
      props.waveColor,
      props.offsetY,
      props.waveSpeed)
  }
}

onMounted(() => {
  toWavePlay()
})
</script>

<template>
  <section :style="{ 'height': props.height, 'background-color': props.bgColor }">
    <canvas ref="canvasRef" class="w-[100%] h-[100%]" />
  </section>
</template>
